import { writable, derived, get as getVal } from "svelte/store";
import { object, string, number, type Asserts } from "yup";
import { user$ } from "@entity/User";

export enum Visibility {
  Private = "private",
  Public = "public",
}

export enum ShowCategory {
  All = "all",
  Admin = "admin",
  Contributor = "contributor",
}

export type Dataset = {
  id: number;
  code: string;
  vis: Visibility;
  user_id?: number;
  name: string;
  desc: string | null;
  maxium_datasets: number;
};

export type ListDatasetParam = {
  show_category: ShowCategory;
};

export type CreateDatasetParam = {
  vis: Visibility;
  name: string;
  desc?: string;
};

export type UpdateDatasetParam = {
  id: number;
  vis?: Visibility;
  name?: string;
  desc?: string;
};

export const DatasetSchema = object({
  id: number().required("数据集id必填"),
  code: string().required("数据集code必填"),
  vis: string().required("数据集visibility必填"),
  user_id: number().required("数据集用户必填"),
  name: string().required("数据集名称必填").max(10, "最多10个字"),
  desc: string().optional().max(20, "最多20个字"),
});

export const CreateDatasetParamSchema = DatasetSchema.omit(["id", "code", "user_id"]);

// type Dataset = Asserts<typeof DatasetSchema>

export const DatasetFactory = (
  id?: number,
  code?: string,
  vis?: Visibility,
  name?: string,
  desc?: string,
  maxium_datasets?: number
): Dataset => {
  return { id, code, vis, name, desc, maxium_datasets };
};

export const userDatasets$ = writable<Dataset[]>([]);
export const currentDatasetIndex$ = writable<number>(-1);
export const currentListDatasetParam$ = writable<ListDatasetParam>({
  show_category: ShowCategory.All,
});

export const currentDataset$ = derived(
  [userDatasets$, currentDatasetIndex$],
  ([$userDatasets$, $currentDatasetIndex$], set: (val: Dataset) => void) => {
    if ($userDatasets$.length > 0 && $currentDatasetIndex$ === -1) {
      currentDatasetIndex$.set(0);
      return
    }
    set(
      $currentDatasetIndex$ === -1
        ? null
        : $userDatasets$[$currentDatasetIndex$]
    );
  }
);

export const setCurrentDatasetByCode = (code: string) => {
  const idx = getVal(userDatasets$).findIndex((v) => v!.code === code);

  if (idx !== -1) {
    currentDatasetIndex$.set(idx);
  }
};

export const syncToUserDatasets = (dataset: Dataset) => {
  let $userDatasets$ = getVal(userDatasets$);
  const idx = $userDatasets$.findIndex((v) => v!.code === dataset.code);
  if (idx !== -1) {
    $userDatasets$[idx] = dataset
  } else {
    $userDatasets$.push(dataset)
  }
  userDatasets$.set($userDatasets$);
}

export const canAddDataset$ = derived(
  [user$, userDatasets$],
  ([$user$, $userDatasets$], set: (v: boolean) => void) => {
    // console.log("$user$.maxium_apps =>", $user$.maxium_datasets);
    // console.log("$userDatasets$.length =>", $userDatasets$.length);
    set($userDatasets$.length < $user$.maxium_datasets);
  }
);